package com.fulu.game.bi.service.impl.value;

import cn.hutool.core.date.DateUtil;
import com.fulu.game.bi.common.util.csv.CsvExportUtil;
import com.fulu.game.bi.common.util.csv.Mapper;
import com.fulu.game.bi.common.util.csv.Querier;
import com.fulu.game.bi.common.util.lang.StringUtils;
import com.fulu.game.bi.entity.bo.channel.ValueRealTimeBO;
import com.fulu.game.bi.entity.bo.channel.ValueSceneListBO;
import com.fulu.game.bi.entity.enums.QueryTypeStatusEnum;
import com.fulu.game.bi.entity.enums.ValueCategoryEnum;
import com.fulu.game.bi.entity.vo.value.ValueAddSceneListVO;
import com.fulu.game.bi.entity.vo.value.ValueAddSceneRealtimeStatVO;
import com.fulu.game.bi.hbase.HBaseValueAddSceneRealtimeStatDAO;
import com.fulu.game.bi.hbase.HBaseValueAddSceneStatDAO;
import com.fulu.game.bi.redis.service.value.ValueAddService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ValueAddServiceImpl extends BaseValueService implements ValueAddService {
    @Autowired
    private HBaseValueAddSceneRealtimeStatDAO hBaseValueAddSceneRealtimeStatDAO;
    @Autowired
    private HBaseValueAddSceneStatDAO hBaseValueAddSceneStatDAO;

    @Override
    public List<ValueAddSceneRealtimeStatVO> realTime(Integer category) {
        ValueRealTimeBO valueRealTimeBO = new ValueRealTimeBO();
        valueRealTimeBO.setCategory(category.toString());
        valueRealTimeBO.setStatDate(DateUtil.today());
        ValueAddSceneRealtimeStatVO today = hBaseValueAddSceneRealtimeStatDAO.findByParameter(valueRealTimeBO);
        valueRealTimeBO.setStatDate(DateUtil.formatDate(DateUtil.offsetDay(new Date(), -1)));
        ValueAddSceneRealtimeStatVO yesterday = hBaseValueAddSceneRealtimeStatDAO.findByParameter(valueRealTimeBO);
        valueRealTimeBO.setStatDate(DateUtil.formatDate(DateUtil.offsetDay(new Date(), -2)));
        ValueAddSceneRealtimeStatVO theDayBeforeYesterday = hBaseValueAddSceneRealtimeStatDAO.findByParameter(valueRealTimeBO);
        valueRealTimeBO.setStatDate(DateUtil.formatDate(DateUtil.offsetDay(new Date(), -8)));
        ValueAddSceneRealtimeStatVO lastWeekYesterdaySameDay = hBaseValueAddSceneRealtimeStatDAO.findByParameter(valueRealTimeBO);
        List<ValueAddSceneRealtimeStatVO> list = new ArrayList<>();
        yesterday.setConsumeUserNumDay(datio(yesterday.getConsumeUserNum(), theDayBeforeYesterday.getConsumeUserNum()));
        yesterday.setConsumeUserNumWeek(datio(yesterday.getConsumeUserNum(), lastWeekYesterdaySameDay.getConsumeUserNum()));
        yesterday.setConsumeNumDay(datio(yesterday.getConsumeNum(), theDayBeforeYesterday.getConsumeNum()));
        yesterday.setConsumeNumWeek(datio(yesterday.getConsumeNum(), lastWeekYesterdaySameDay.getConsumeNum()));
        yesterday.setVirtualMoneyAllDay(datio(yesterday.getVirtualMoneyAll(), theDayBeforeYesterday.getVirtualMoneyAll()));
        yesterday.setVirtualMoneyAllWeek(datio(yesterday.getVirtualMoneyAll(), lastWeekYesterdaySameDay.getVirtualMoneyAll()));
        yesterday.setCharmMoneyAllDay(datio(yesterday.getCharmMoneyAll(), theDayBeforeYesterday.getCharmMoneyAll()));
        yesterday.setCharmMoneyAllWeek(datio(yesterday.getCharmMoneyAll(), lastWeekYesterdaySameDay.getCharmMoneyAll()));
        list.add(today);
        list.add(yesterday);
        return list;
    }

    @Override
    public PageInfo<ValueAddSceneListVO> list(ValueSceneListBO valueSceneListBO) {
        valueSceneListBO.setTableName(valueAddSceneStatMap.get(valueSceneListBO.getQueryType()));
        valueSceneListBO.setPageNum((valueSceneListBO.getPageNum() - 1) * valueSceneListBO.getPageSize());
        valueSceneListBO = handleBO(valueSceneListBO);
        List<ValueAddSceneListVO> list = hBaseValueAddSceneStatDAO.list(valueSceneListBO);
        Integer count = hBaseValueAddSceneStatDAO.count(valueSceneListBO);
        PageInfo<ValueAddSceneListVO> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(count == null ? 0 : count);
        ValueSceneListBO finalValueSceneListBO = valueSceneListBO;
        list = list.stream().map(map -> {
            if (Objects.equals(finalValueSceneListBO.getGiftType(), "全部") || finalValueSceneListBO.isAllGiftType()) {
                map.setGiftType("/");
            }
            map.setQueryType(finalValueSceneListBO.getQueryType());
            return map;
        }).collect(Collectors.toList());
        PageInfo<ValueAddSceneListVO> voPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(pageInfo, voPageInfo);
        voPageInfo.setList(list);
        return voPageInfo;
    }

    private ValueSceneListBO handleBO(ValueSceneListBO valueSceneListBO) {
        //宝箱和礼盒全部类型，查礼物类型和对应的礼物类型
        if (!Objects.equals(valueSceneListBO.getCategory(), ValueCategoryEnum.GIFT.getType()) && StringUtils.isEmpty(valueSceneListBO.getGiftType())) {
            valueSceneListBO.setGiftType(ValueCategoryEnum.getEnum(valueSceneListBO.getCategory()).getName());
            valueSceneListBO.setCategory(ValueCategoryEnum.GIFT.getType());
            valueSceneListBO.setAllGiftType(true);
        }
        return valueSceneListBO;
    }

    @Override
    public void export(ValueSceneListBO bo) {
        String fileName = "增值场景";
        LinkedHashMap<String, Mapper<ValueAddSceneListVO>> map = new LinkedHashMap<>();
        QueryTypeStatusEnum anEnum = QueryTypeStatusEnum.getEnum(bo.getQueryType());
        switch (anEnum) {
            case DAY:
                map.put("日期", v -> v.getStartDate());
                break;
            default:
                map.put("日期", v -> v.getStartDate() + "-" + v.getEndDate());
                break;
        }
        map.put("礼物类型", v -> v.getGiftType());
        map.put("消费人数", v -> v.getConsumeUserNum() + "");
        map.put("消费次数", v -> v.getConsumeNum() + "");
        map.put("消费金额", v -> v.getVirtualMoneyAll() + "");
        map.put("消费数量", v -> v.getAmount() + "");
        map.put("魅力值", v -> v.getCharmMoneyAll() + "");
        if (!Objects.equals(bo.getCategory(), 1)) {
            map.put("收益", v -> v.getEarnings() + "");
        }
        Querier querier = (num) -> list(bo);
        CsvExportUtil.export(100, fileName, map, querier);
    }


    @Override
    public List<String> giftType(Integer category, Integer queryType) {
        String tableName = valueAddSceneStatMap.get(queryType);
        List<String> list = hBaseValueAddSceneStatDAO.getGiftTypeByCategory(category + "", tableName);
        return list.stream().filter(map -> !Objects.equals(map, "全部")).collect(Collectors.toList());
    }

    @Override
    public List<ValueAddSceneListVO> lineList(ValueSceneListBO valueSceneListBO) {
        valueSceneListBO.setTableName(valueAddSceneStatMap.get(valueSceneListBO.getQueryType()));
        valueSceneListBO = handleBO(valueSceneListBO);
        List<ValueAddSceneListVO> list = hBaseValueAddSceneStatDAO.lineList(valueSceneListBO);
        ValueSceneListBO finalValueSceneListBO = valueSceneListBO;
        return list.stream().map(map -> {
            if (Objects.equals(finalValueSceneListBO.getGiftType(), "全部")) {
                map.setGiftType("/");
            }
            map.setQueryType(finalValueSceneListBO.getQueryType());
            return map;
        }).collect(Collectors.toList());
    }

    private BigDecimal datio(BigDecimal a, BigDecimal b) {
        if (Objects.isNull(b) || b.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return a.subtract(b).divide(b, 2, BigDecimal.ROUND_HALF_DOWN);
    }
}
